package ai.wprolog.essentials;

import java.util.Hashtable;

/** Simple a list of terms. */
public class TermList {
	Term term;
	TermList next;

	// The next two are initialised in ParseString.consult
	public TermList definer[] = null; // where is this atom defined?
	public int numclauses = 0; // How many clauses define this atom?

	public TermList(Term t, TermList n) {
		term = t;
		next = n;
	}

	public TermList(Term t, TermList n, TermList d) {
		term = t;
		next = n;
		definer = d.definer;
		numclauses = d.numclauses;
	}

	public final String toString() {
		String s;
		TermList tl;
		s = new String("[" + term.toString());
		tl = next;
		while (tl != null) {
			s = s + ", " + tl.term.toString();
			tl = tl.next;
		}

		if (definer != null)
			s = s + "( " + numclauses + " clauses)";

		return s + "]";
	}

	/** Looks up which clauses define atoms once and for all */
	public void resolve(Hashtable db) {
		if (definer == null) {
			numclauses = 0;
			while (db.get(term.getfunctor() + "/" + term.getarity() + "-"
					+ (1 + numclauses)) != null)
				numclauses++;

			definer = new TermList[numclauses + 1]; // start numbering at 1

			for (int i = 1; i <= numclauses; i++) {
				definer[i] = (TermList) db.get(term.getfunctor() + "/"
						+ term.getarity() + "-" + (i));
				// IO.trace("resolve: " + term.getfunctor() + "/" +
				// term.getarity() + "-" + i +
				// " = " + definer[i]);
			}

			if (next != null)
				next.resolve(db);
		}
	}

	/** Used for parsing clauses. */
	public TermList(ParseString ps) throws Exception {
		Term ts[];
		int i = 0;
		TermList tsl[];

		ts = new Term[300]; // arbitrary
		tsl = new TermList[300]; // arbitrary

		ts[i++] = new Term(ps);
		ps.skipspace();

		if (ps.current() == ':') {
			ps.advance();

			if (ps.current() != '-')
				ps.parseerror("Expecting ``-'' after ``:''");

			ps.advance();
			ps.skipspace();

			ts[i++] = new Term(ps);
			ps.skipspace();

			while (ps.current() == ',') {
				ps.advance();
				ps.skipspace();
				ts[i++] = new Term(ps);
				ps.skipspace();
			}

			tsl[i] = null;

			for (int j = i - 1; j > 0; j--)
				tsl[j] = new TermList(ts[j], tsl[j + 1]);

			term = ts[0];
			next = tsl[1];

		} else {
			term = ts[0];
			next = null;
		}

		if (ps.current() != '.')
			ps.parseerror("Expecting ``.''");

		ps.advance();
	}
}